home *** CD-ROM | disk | FTP | other *** search
/ Aminet 25 / Aminet 25 (1998)(GTI - Schatztruhe)[!][Jun 1998].iso / Aminet / util / pack / xpk_Source.lha / xpk_Source / prefs / XpkMasterPrefs.c < prev   
C/C++ Source or Header  |  1998-02-08  |  17KB  |  633 lines

  1. #define NAME        "XpkMasterPrefs"
  2. #define DISTRIBUTION    "(Freeware) "
  3. #define REVISION    "17"
  4. #define DEBUG
  5.  
  6. /* Programmheader
  7.  
  8.     Name:        XpkMasterPrefs
  9.     Author:        SDI
  10.     Distribution:    Freeware
  11.     Description:    xpk prefs loader, like IPrefs
  12.     Compileropts:    -
  13.     Linkeropts:    -gsi (no startup)
  14.  
  15.  1.0   25.12.96 : first Version
  16.  1.1   26.12.96 : nearly redefined xpkprefs structures - a lot of changes
  17.  1.2   27.12.96 : some fixes
  18.  1.3   30.12.96 : did a bit on Recog function
  19.  1.4   02.01.97 : added correctness check of BufPattern
  20.  1.5   11.01.97 : corrected some errors
  21.  1.6   28.02.97 : changed some semaphore specific stuff
  22.  1.7   01.03.97 : added Version info to MainPrefs
  23.  1.8   07.03.97 : fixed RecogFunc
  24.  1.9   24.03.97 : added DEBUG stuff
  25.  1.10  28.03.97 : added last function and ReadArgs
  26.  1.11  02.04.97 : XpkTypeData changed, ListData now internal structure
  27.  1.12  03.04.97 : added DEBUG info, debuged RecogFunction
  28.  1.13  04.04.97 : buffer now 2 K
  29.  1.14  06.06.97 : name pattern no case independant
  30.  1.15  17.06.97 : fixed error, when no name and no filepattern
  31.  1.16  18.06.97 : added filelength check and OR parameter
  32.  1.17  13.08.97 : fixed Enforcer hit
  33. */
  34.  
  35. /*
  36. How to parse the type list:
  37. - The struct XpkTypeData of the first matching structure is returned.
  38. - If no type matches, the default is returned.
  39. - Scan goes always in linear order from the beginning to end. (and never
  40.   reverse).
  41. - if no file name is given, the xtp_FilePattern field is ignored.
  42. */
  43.  
  44. #include <proto/exec.h>
  45. #include <proto/dos.h>
  46. #include <proto/iffparse.h>
  47. #include <utility/tagitem.h>
  48. #include <prefs/prefhdr.h>
  49. #include <xpk/xpkprefs.h>
  50. #include <exec/memory.h>
  51. #include "SDI_defines.h"
  52. #define SDI_TO_ANSI
  53. #include "SDI_ASM_STD_protos.h"
  54.  
  55.  
  56. /**************************************************************************
  57.  *
  58.  * Standard prefs specific data structure. xps_PrefsData points to this.
  59.  *
  60.  * xssd_TypeList nodes are of type XpkTypeNode.
  61.  *
  62.  * 
  63.  */
  64.  
  65. struct XpkStdSemaphoreData {
  66.   struct List    xssd_TypeList;     /* list of file types */
  67.   ULONG        xssd_Buffer1Size;  /* size of following buffer */
  68.   STRPTR    xssd_Buffer1;       /* pointer to buffer */
  69. };
  70.  
  71. struct XpkTypeNode {
  72.   struct Node        xtn_Node;    /* standard node structure */
  73.   ULONG            xtn_Size;    /* hold complete size to free */
  74.   struct XpkTypePrefs    xtn_TypePrefs;  /* real data */
  75. };
  76.  
  77. #define RECOGBUFSIZE    2048
  78.  
  79. #define PARAM "QUIT/S"
  80.  
  81. #ifdef __MAXON__
  82.   #define __asm
  83.   struct Library *IFFParseBase;
  84. #else
  85.   #define iffparsebase    IFFParseBase
  86. #endif
  87.  
  88. struct DosLibrary *DOSBase;
  89.  
  90. void CorrectAdr(APTR pos, APTR mempos);
  91. void DoPrefsCreation(struct XpkPrefsSemaphore *sem);
  92. void ClearTypeList(struct XpkStdSemaphoreData *sem);
  93. void ClearMainPrefs(struct XpkPrefsSemaphore *sem);
  94. struct XpkTypeData * __asm RecogFunc(register __a0 STRPTR buf,
  95. register __a1 STRPTR name, register __d0 ULONG bufsize,
  96. register __d1 ULONG fullsize, register __a2 struct TagItem *);
  97.  
  98. UBYTE CheckHex(STRPTR *data, LONG number);
  99. ULONG CheckBufPattern(STRPTR pattern);
  100. UBYTE GetCharacter(STRPTR pattern);
  101. /* these two return zero, when name matches or defined values, when not */
  102. ULONG CheckPattern(STRPTR pattern, STRPTR buffer, ULONG size, ULONG fsize);
  103. ULONG MatchBufPattern(STRPTR pattern, STRPTR buffer, ULONG size, ULONG fsize);
  104. ULONG MatchFileName(STRPTR pattern, STRPTR name);
  105.  
  106. #define MATCHERR_PATTERN_INCORRECT    1
  107. #define MATCHERR_NO_MEMORY        2
  108. #define MATCHERR_BUFFER_TO_SHORT    3
  109. #define MATCHERR_NO_MATCH        4
  110. #define MATCHERR_NO_SIZE_MATCH        5
  111.  
  112. ULONG start(void) /* not named main, to get error with startup code ! */
  113. {
  114.   struct DosLibrary *dosbase;
  115.   struct XpkPrefsSemaphore *semaphore;
  116.   struct Process *task;
  117.   struct Message *msg = 0;
  118.   struct RDArgs *rda;
  119.   LONG quit = 0;
  120.  
  121.   if(!(task = (struct Process *) FindTask(0))->pr_CLI)
  122.   {
  123.     WaitPort(&task->pr_MsgPort);
  124.     msg = GetMsg(&task->pr_MsgPort);
  125.     /* no tooltype check now, so means always start semaphore */
  126.   }
  127.   else
  128.   {
  129.     if((dosbase = (struct DosLibrary *) OpenLibrary("dos.library", 37)))
  130.     {
  131.       DOSBase = dosbase;
  132.       if((rda = ReadArgs(PARAM, &quit, 0)))
  133.         FreeArgs(rda);
  134.       CloseLibrary((struct Library *) dosbase);
  135.     }
  136.     /* does not recognize failed ReadArgs - normal start in this case */
  137.   }
  138.  
  139.   if(quit)
  140.   {
  141.     Forbid();
  142.     if((semaphore = (struct XpkPrefsSemaphore *) FindSemaphore(XPKPREFSSEMNAME)))
  143.     {
  144.       ObtainSemaphoreShared((struct SignalSemaphore *) semaphore);
  145.         Signal(semaphore->xps_MasterTask, SIGBREAKF_CTRL_C);
  146.       ReleaseSemaphore((struct SignalSemaphore *) semaphore);
  147.     }
  148.     Permit();
  149.   }
  150.   else if(!FindSemaphore(XPKPREFSSEMNAME) &&
  151.   (dosbase = (struct DosLibrary *) OpenLibrary("dos.library", 37)))
  152.   {
  153.     DOSBase = dosbase;
  154.     if((semaphore = (struct XpkPrefsSemaphore *) AllocMem(sizeof(struct
  155.     XpkPrefsSemaphore) + sizeof(struct XpkStdSemaphoreData), MEMF_PUBLIC|MEMF_CLEAR)))
  156.     {
  157.       struct NotifyRequest *notifyrequest;
  158.  
  159.       struct XpkStdSemaphoreData *sd = (struct XpkStdSemaphoreData *)
  160.        (((STRPTR) semaphore) + sizeof(struct XpkPrefsSemaphore));
  161.         /* both structures are allocated with one AllocMem */
  162.  
  163.       semaphore->xps_Semaphore.ss_Link.ln_Type = NT_SEMAPHORE;
  164.       semaphore->xps_Semaphore.ss_Link.ln_Name = XPKPREFSSEMNAME;
  165.       semaphore->xps_PrefsData = sd;
  166. //    semaphore->xps_Version = 0;
  167.       semaphore->xps_PrefsType = XPREFSTYPE_STANDARD;
  168. //    semaphore->xps_ProgressFunc = 0;
  169.       semaphore->xps_RecogSize = RECOGBUFSIZE;
  170.       semaphore->xps_RecogFunc = (struct XpkTypeData *(*)()) RecogFunc;
  171.       semaphore->xps_MasterTask = (struct Task *) task;
  172.  
  173.       sd->xssd_TypeList.lh_Type = NT_USER;
  174.       sd->xssd_TypeList.lh_Head = (struct Node *) &sd->xssd_TypeList.lh_Tail;
  175.       sd->xssd_TypeList.lh_TailPred = (struct Node *) &sd->xssd_TypeList.lh_Head;
  176.  
  177.       InitSemaphore((struct SignalSemaphore *) semaphore);
  178.       AddSemaphore((struct SignalSemaphore *) semaphore);
  179.  
  180.       if((notifyrequest = (struct NotifyRequest *)
  181.       AllocMem(sizeof(struct NotifyRequest), MEMF_CLEAR)))
  182.       {
  183.         ULONG signr;
  184.  
  185.         if((signr = AllocSignal(-1L)) != -1)
  186.         {
  187.           notifyrequest->nr_Name = "ENV:xpkmaster.prefs";
  188.           notifyrequest->nr_Flags = NRF_SEND_SIGNAL | NRF_NOTIFY_INITIAL;
  189.           notifyrequest->nr_stuff.nr_Signal.nr_Task = FindTask(0);
  190.           notifyrequest->nr_stuff.nr_Signal.nr_SignalNum = signr;
  191.           if((StartNotify(notifyrequest)) == DOSTRUE)
  192.           {
  193.         ULONG signal = 0;
  194.             while(!(signal & SIGBREAKF_CTRL_C))
  195.               if((signal = Wait(1 << signr | SIGBREAKF_CTRL_C)) & (1 << signr))
  196.             DoPrefsCreation(semaphore);
  197.             EndNotify(notifyrequest);
  198.           }
  199.           FreeSignal(signr);
  200.         }
  201.         FreeMem(notifyrequest, sizeof(struct NotifyRequest));
  202.       }
  203.       ObtainSemaphore((struct SignalSemaphore *) semaphore);
  204.       RemSemaphore((struct SignalSemaphore *) semaphore);
  205.       ClearTypeList((struct XpkStdSemaphoreData *) semaphore->xps_PrefsData);
  206.       ClearMainPrefs(semaphore);
  207.  
  208.       FreeMem(semaphore, sizeof(struct XpkPrefsSemaphore) +
  209.         sizeof(struct XpkStdSemaphoreData));
  210.     }
  211.     CloseLibrary((struct Library *) dosbase);
  212.   }
  213.  
  214.   if(msg)
  215.   {
  216.     Forbid();
  217.     ReplyMsg(msg);
  218.   }
  219.  
  220.   return 0;
  221. }
  222.  
  223. /* changes relative addresses into normal ones */
  224. void CorrectAdr(APTR pos, APTR mempos)
  225. {
  226.   if(*(ULONG *)pos)
  227.     *(ULONG *)pos += (ULONG) mempos;
  228. }
  229.  
  230. void ClearTypeList(struct XpkStdSemaphoreData *sd)
  231. {
  232.   struct Node *n;
  233.  
  234.   while((n = RemHead(&sd->xssd_TypeList)))
  235.     FreeMem(n, ((struct XpkTypeNode *) n)->xtn_Size);
  236. }
  237.  
  238. void ClearMainPrefs(struct XpkPrefsSemaphore *sem)
  239. {
  240.   struct XpkStdSemaphoreData *sd = (struct XpkStdSemaphoreData *) sem->xps_PrefsData;
  241.   if(sd->xssd_Buffer1)
  242.     FreeMem(sd->xssd_Buffer1, sd->xssd_Buffer1Size);
  243.   sem->xps_MainPrefs = 0;
  244.   sd->xssd_Buffer1Size = 0;
  245.   sd->xssd_Buffer1 = 0;
  246. }
  247.  
  248. void DoPrefsCreation(struct XpkPrefsSemaphore *sem)
  249. {
  250.   struct Library *iffparsebase;
  251.   struct ContextNode  *cn;
  252.   struct IFFHandle *iff;
  253.   ULONG prefsversion = 0;
  254.  
  255.   ObtainSemaphore(&sem->xps_Semaphore);
  256.  
  257.   ClearTypeList((struct XpkStdSemaphoreData *) sem->xps_PrefsData);
  258.   ClearMainPrefs(sem);
  259.  
  260.   if(!(iffparsebase = OpenLibrary("iffparse.library", 37)))
  261.     return;
  262.  
  263. #ifdef __MAXON__
  264.   IFFParseBase = iffparsebase;
  265. #endif
  266.  
  267.   if((iff = AllocIFF()))
  268.   {
  269.     if((iff->iff_Stream = Open("ENV:xpkmaster.prefs", MODE_OLDFILE)))
  270.     {
  271.       InitIFFasDOS(iff);
  272.       if(!OpenIFF(iff, IFFF_READ))
  273.       {
  274.     LONG a[] = { ID_PREF, ID_PRHD, ID_PREF, ID_XPKT, ID_PREF, ID_XPKM};
  275.     if(!StopChunks(iff, a, 3))
  276.     {
  277.       ULONG error = 0;
  278.  
  279.       while(!error)
  280.           {
  281.             if(ParseIFF(iff,IFFPARSE_SCAN))
  282.               break;
  283.  
  284.             cn = CurrentChunk(iff);
  285.  
  286.         switch(cn->cn_ID)
  287.         {
  288.         case ID_PRHD:
  289.           {
  290.             struct PrefHeader prh;
  291.             ReadChunkBytes(iff, &prh, sizeof(struct PrefHeader));
  292.             prefsversion = prh.ph_Version;
  293.     /* use this, when internal version is greater than one. In this
  294.        case the value is version of XPKT chunks */
  295.           } break;
  296.         case ID_XPKT:
  297.           {
  298.             struct XpkTypeNode *buf;
  299.         ULONG size;
  300.             size = cn->cn_Size + sizeof(struct Node) + sizeof(ULONG);
  301.             if((buf = (struct XpkTypeNode *) AllocMem(size, MEMF_PUBLIC|MEMF_CLEAR)))
  302.             {
  303.           struct XpkTypePrefs *pref = &buf->xtn_TypePrefs;
  304.  
  305.               ReadChunkBytes(iff, pref, cn->cn_Size);
  306.           CorrectAdr(&pref->xtp_NamePattern, pref);
  307.           CorrectAdr(&pref->xtp_FilePattern, pref);
  308.           CorrectAdr(&pref->xtp_TypeName, pref);
  309.           CorrectAdr(&pref->xtp_PackerData, pref);
  310.           buf->xtn_Node.ln_Name = pref->xtp_TypeName;
  311.           buf->xtn_Node.ln_Type = NT_USER;
  312.           buf->xtn_Size = size;
  313.           pref->xtp_PackerData->xtd_Memory = 0;
  314.           pref->xtp_PackerData->xtd_MemorySize = 0;
  315.           AddTail(&((struct XpkStdSemaphoreData *)sem->xps_PrefsData)->xssd_TypeList, (struct Node *) buf);
  316.             }
  317.             else error = 1;
  318.           } break;
  319.         case ID_XPKM:
  320.           {
  321.         struct XpkMainPrefs *pref;
  322.         struct XpkStdSemaphoreData *sd =
  323.           (struct XpkStdSemaphoreData *) sem->xps_PrefsData;
  324.         struct XpkTypeData *p;
  325.  
  326.         ClearMainPrefs(sem);
  327.  
  328.             if((pref = (struct XpkMainPrefs *) AllocMem(cn->cn_Size, MEMF_PUBLIC|MEMF_CLEAR)))
  329.             {
  330.               ReadChunkBytes(iff, pref, cn->cn_Size);
  331.           CorrectAdr(&pref->xmp_DefaultType, pref);
  332.           p = pref->xmp_DefaultType;
  333.     /* XpkTypeData newer than version 0 may be incorrect, so set to 0 */
  334.           p->xtd_Version = 0;
  335.           p->xtd_Memory = 0;
  336.           p->xtd_MemorySize = 0;
  337.           sem->xps_MainPrefs = pref;
  338.                   sd->xssd_Buffer1Size = cn->cn_Size;
  339.                   sd->xssd_Buffer1 = (STRPTR) pref;
  340.         }
  341.         else error = 1;
  342.           } break;
  343.         }
  344.       }
  345.     }
  346.         CloseIFF(iff);
  347.       }
  348.       Close(iff->iff_Stream);
  349.     }
  350.     FreeIFF(iff);
  351.   }
  352.   CloseLibrary(IFFParseBase);
  353.   ReleaseSemaphore(&sem->xps_Semaphore);
  354. }
  355.  
  356. UBYTE CheckHex(STRPTR *data, LONG number)
  357. {
  358.   LONG num;
  359.   do
  360.   {
  361.     num = number;
  362.     while(num-- && isxdigit(*((*data)++)))
  363.       ;
  364.     if(++num)
  365.       return MATCHERR_PATTERN_INCORRECT;
  366.   } while(isxdigit(**data));
  367.   return 0;
  368. }
  369.  
  370. /* return 0, when pattern is valid */
  371. ULONG CheckBufPattern(STRPTR pattern)
  372. {
  373.   while(*pattern)
  374.   {
  375.     ULONG a;
  376.     STRPTR s;
  377.     
  378.     s = pattern;
  379.  
  380.     switch(*(pattern++))
  381.     {
  382.     case 'l': a = 1; break;
  383.     case 'h': a = 1; break;
  384.     case 'm': a = 1; break;
  385.     case 'v': a = 2; break;
  386.     case 'r': a = 4; break;
  387.     case 'g': a = 4; break;
  388.     case 's': a = 2; break;
  389.     case '|': a = 0; break;
  390.     default: return MATCHERR_PATTERN_INCORRECT; break;
  391.     }
  392.     if(a && CheckHex(&pattern, a))
  393.       return MATCHERR_PATTERN_INCORRECT;
  394.  
  395.     if((*s == 'm' && (pattern-s) > 5) ||
  396.     ((*s == 'l' || *s == 'h') && (pattern-s) > 9))
  397.       return MATCHERR_PATTERN_INCORRECT;
  398.     /* only word data for 'm' and longword for 'l' and 'h' + 1 '.' */
  399.   }
  400.  
  401.   return 0;
  402. }
  403.  
  404. UBYTE GetCharacter(STRPTR pattern)
  405. {
  406.   UBYTE i = 0, c;
  407.   ULONG size = 2;
  408.   while(size--)
  409.   {
  410.     i <<= 4;
  411.     if((c = toupper(*(pattern++))) >= 'A')
  412.       i += c + 10 - 'A';
  413.     else
  414.       i += c - '0';
  415.   }
  416.   return i;
  417. }
  418.  
  419. ULONG CheckPattern(STRPTR pattern, STRPTR buffer, ULONG size, ULONG fsize)
  420. {
  421.   STRPTR bufpos = buffer;
  422.   ULONG i;
  423.   UBYTE j, k;
  424.   STRPTR errpos, str;
  425.  
  426.   while(pattern && *pattern && *pattern != '|')
  427.   {
  428.     switch(*(pattern++))
  429.     {
  430.     case 'm':
  431.       i = strtoul(pattern, &errpos, 16);
  432.       pattern = errpos; /* first non hex char is next command */
  433.       if(i >= size)
  434.         return MATCHERR_BUFFER_TO_SHORT;
  435.       else
  436.         bufpos = buffer + i;
  437.       break;
  438.     case 'l':
  439.       i = strtoul(pattern, &errpos, 16);
  440.       pattern = errpos; /* first non hex char is next command */
  441.       if(fsize > i)
  442.         return MATCHERR_NO_SIZE_MATCH;
  443.       break;
  444.     case 'h':
  445.       i = strtoul(pattern, &errpos, 16);
  446.       pattern = errpos; /* first non hex char is next command */
  447.       if(fsize < i)
  448.         return MATCHERR_NO_SIZE_MATCH;
  449.       break;
  450.     case 'v':
  451.       while(isxdigit(*pattern))
  452.       {
  453.     j = GetCharacter(pattern); pattern += 2;
  454.         if(bufpos >= buffer + size)
  455.           return MATCHERR_BUFFER_TO_SHORT;
  456.     if(j != *(bufpos++))
  457.       return MATCHERR_NO_MATCH;
  458.       }
  459.       break;
  460.     case 'r':
  461.       while(isxdigit(*pattern))
  462.       {
  463.     errpos = buffer;
  464.     k = GetCharacter(pattern); pattern += 2;
  465.     j = GetCharacter(pattern); pattern += 2;
  466.         while(errpos < buffer + size)
  467.         {
  468.       if(*errpos >= k && *errpos <= j)
  469.         return MATCHERR_NO_MATCH;
  470.       ++errpos;
  471.     }
  472.       }
  473.       break;
  474.     case 'g':
  475.       while(isxdigit(*pattern))
  476.       {
  477.     k = GetCharacter(pattern); pattern += 2;
  478.     j = GetCharacter(pattern); pattern += 2;
  479.         if(bufpos >= buffer + size)
  480.           return MATCHERR_BUFFER_TO_SHORT;
  481.     if(*bufpos < k && *bufpos > j)
  482.       return MATCHERR_NO_MATCH;
  483.     ++bufpos;
  484.       }
  485.       break;
  486.     case 's':
  487.       bufpos = buffer;
  488.       while(isxdigit(*pattern))
  489.       {
  490.         str = pattern;
  491.     j = GetCharacter(str); str += 2;
  492.     while(bufpos < buffer + size && *bufpos != j)
  493.       ++bufpos;
  494.     if(*bufpos == j)
  495.     {
  496.       errpos = ++bufpos;
  497.           while(isxdigit(*str) && bufpos < buffer + size && 
  498.           GetCharacter(str) == *bufpos)
  499.           {
  500.         str += 2; ++bufpos;
  501.       }
  502.       if(!isxdigit(*str))
  503.         pattern = str;    /* exits while loop */
  504.       else
  505.         bufpos = errpos; /* reset buffer */
  506.         }
  507.         else
  508.       return MATCHERR_NO_MATCH;
  509.       }
  510.       break;
  511.     default: return MATCHERR_NO_MATCH; break;
  512.     }
  513.   }
  514.   return 0;
  515. }
  516.  
  517. ULONG MatchBufPattern(STRPTR pattern, STRPTR buffer, ULONG size, ULONG fsize)
  518. {
  519.   ULONG err = MATCHERR_NO_MATCH;
  520.  
  521.   if(!pattern || CheckBufPattern(pattern))
  522.   {
  523. #ifdef DEBUG
  524.     Printf("MatchBufPattern: CheckBufPattern(%s) failed\n", pattern);
  525. #endif
  526.     return MATCHERR_PATTERN_INCORRECT;
  527.   }
  528.  
  529.   while(*pattern)
  530.   {
  531.     if(!(err = CheckPattern(pattern, buffer, size, fsize)))
  532.       return 0;
  533.     else /* search for next OR field or end of pattern */
  534.     {
  535.       while(*pattern && *pattern != '|')
  536.         ++pattern;
  537.       if(*pattern == '|')
  538.         ++pattern;
  539.     }
  540.   }
  541.  
  542.   return err;
  543. }
  544.  
  545. ULONG MatchFileName(STRPTR pattern, STRPTR name)
  546. {
  547.   ULONG a, b = MATCHERR_NO_MATCH;
  548.   STRPTR buf;
  549.  
  550.   if(!pattern)
  551.     return MATCHERR_PATTERN_INCORRECT;
  552.  
  553.   a = (strlen(pattern)<<1) + 10; /* pattern match buffer */
  554.  
  555.   if(!(buf = (STRPTR) AllocMem(a, MEMF_ANY)))
  556.     return MATCHERR_NO_MEMORY;
  557.  
  558.   if(ParsePatternNoCase(pattern, buf, a) >= 0 && MatchPatternNoCase(buf, name))
  559.     b = 0;
  560.  
  561.   FreeMem(buf, a);
  562.  
  563.   return b;
  564. }
  565.  
  566. struct XpkTypeData * __asm RecogFunc(register __a0 STRPTR buf,
  567. register __a1 STRPTR name, register __d0 ULONG bufsize,
  568. register __d1 ULONG fullsize, register __a2 struct TagItem *tags)
  569. {
  570.   struct XpkPrefsSemaphore *sem;
  571.   struct XpkTypePrefs *xp;
  572.   struct Node *n;
  573.  
  574. #ifdef DEBUG
  575.   if(tags)
  576.   {
  577.     while(tags->ti_Tag)
  578.       VPrintf("%ld %ld\n", tags++);
  579.   }
  580. #endif
  581.  
  582.   if(!buf || !bufsize)
  583.     return 0;
  584.  
  585.   sem = (struct XpkPrefsSemaphore *) FindSemaphore(XPKPREFSSEMNAME);
  586.   /* I can do without ObtainSemaphore, because when I'm called here the
  587.   semaphore is owned already and surely exists */
  588.  
  589.   if(sem->xps_PrefsData)
  590.   {
  591.     for(n = ((struct XpkStdSemaphoreData *)sem->xps_PrefsData)->
  592.       xssd_TypeList.lh_Head; n->ln_Succ; n = n->ln_Succ)
  593.     {
  594.       xp = &((struct XpkTypeNode *) n)->xtn_TypePrefs;
  595.  
  596.       if((name && xp->xtp_Flags & XPKT_NamePattern) ||
  597.       xp->xtp_Flags & XPKT_FilePattern)
  598.       {
  599.         if(!(xp->xtp_Flags & XPKT_FilePattern) || !MatchBufPattern(
  600.         xp->xtp_FilePattern, buf, bufsize, fullsize))
  601.         {
  602.           if(!name || !(xp->xtp_Flags & XPKT_NamePattern) || !MatchFileName(
  603.           xp->xtp_NamePattern, name))
  604.       {
  605. #ifdef DEBUG
  606.             Printf("RecogFunc: matched '%s'\n", xp->xtp_TypeName);
  607. #endif
  608.             return xp->xtp_PackerData;
  609.       }
  610. #ifdef DEBUG
  611.           else
  612.             Printf("RecogFunc: no namematch '%s'\n", xp->xtp_TypeName);
  613. #endif
  614.         }
  615. #ifdef DEBUG
  616.         else
  617.           Printf("RecogFunc: no bufmatch '%s'\n", xp->xtp_TypeName);
  618. #endif
  619.       }
  620. #ifdef DEBUG
  621.       else
  622.         Printf("RecogFunc: no patterns '%s'\n", xp->xtp_TypeName);
  623. #endif
  624.     }
  625.   }
  626.  
  627.   if(sem->xps_MainPrefs)
  628.     return sem->xps_MainPrefs->xmp_DefaultType;
  629.  
  630.   return 0;
  631. }
  632.  
  633.